use std::borrow::Borrow;
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use std::time::Duration;

fn main() {
    let name = String::from("hboot");

    let thread = thread::spawn(move || {
        thread::sleep(Duration::from_millis(2));
        println!("hello! - {}", name);
    });
    // drop(name);

    thread.join().unwrap();
    println!("rust!");

    // thread.join().unwrap();

    // let (send, receive) = mpsc::channel();

    // let send_str = send.clone();
    // thread::spawn(move || {
    //     // let name = String::from("rust");
    //     // send_str.send(name).unwrap();

    //     // println!("{}", name);

    //     send_str.send("hello").unwrap();
    //     thread::sleep(Duration::from_millis(2));
    //     send_str.send("rust").unwrap();
    // });

    // let receive_str = receive.recv().unwrap();

    // println!("get thread msg :{}", receive_str);

    // thread::spawn(move || {
    //     // send.send(1).unwrap();
    //     // send.send(10).unwrap();
    //     // send.send(100).unwrap();
    //     send.send("good").unwrap();
    //     thread::sleep(Duration::from_millis(2));
    //     send.send("hboot").unwrap();
    // });

    // // let receive_str = receive.recv().unwrap();
    // // println!("{:?}", receive_str);
    // // let receive_str = receive.recv().unwrap();
    // // println!("{:?}", receive_str)
    // for receive_str in receive {
    //     println!("{}", receive_str);
    // }

    let name = Mutex::new(String::from("hboot"));

    {
        let mut name: std::sync::MutexGuard<'_, String> = name.lock().unwrap();

        *name += " good!";
    }

    println!("{:?}", name.lock().unwrap());

    let name = Arc::new(Mutex::new(String::from("hboot")));

    let mut thread_arr = vec![];
    for val in ["admin", "test", "hello", "rust"] {
        let name = Arc::clone(&name);

        let thread = thread::spawn(move || {
            let mut name = name.lock().unwrap();

            *name += val;
        });

        thread_arr.push(thread);
    }

    for thread in thread_arr {
        thread.join().unwrap();
    }
    println!("{:?}", name.lock().unwrap());

    let user = User::new();

    user.mix(" hello");
    println!("{:?}", user.name.borrow());

    let s = Rc::new(RefCell::new(String::from("hboot")));

    let s1 = Rc::clone(&s);

    let s2 = Rc::clone(&s);

    *s.borrow_mut() += " good";
    println!("{:?}", s1);
}

pub trait Iterator {
    type Item;

    fn next(&mut self) -> Option<Self::Item>;
}

pub trait MixName {
    fn mix(&self, suffix: &str);
}

struct User {
    name: RefCell<String>,
}

impl User {
    fn new() -> User {
        User {
            name: RefCell::new(String::from("hboot")),
        }
    }
}

impl MixName for User {
    fn mix(&self, suffix: &str) {
        self.name.borrow_mut().push_str(suffix);
    }
}
